<template>
  <table-generation
      :list="list"
      :config="config"
      ref="table"
      @afterInit="afterInit"
      @afterDialogInit="afterDialogInit"
      @formChange="formChange"
      @queryChange="queryChange"
      @close="close"
      @closeDialog="closeDialog"
      @tableDataChange="tableDataChange"
      @tableDataChangeV2="tableDataChangeV2"
      @tableDeleteDataNew="tableDeleteDataNew"
      @buttonClicked="buttonClicked"
      @resetQuery="resetQuery"
      @tableRowClick="tableRowClick"
  >
    <template #queryBox>
      <!--会替代查询条件区域-->
    </template>
    <template #buttonPrefix="{ rawAuth, auth }">
      <!--【常用】操作按钮区域最前边-->
      <!--rawAuth最常用，表示菜单按钮权限，auth不常用，表示经过组件内部特殊处理的菜单按钮权限-->
    </template>
    <template #button="{ rawAuth, auth }">
      <!--【极其常用】操作按钮区域最后边-->
      <!--rawAuth最常用，表示菜单按钮权限，auth不常用，表示经过组件内部特殊处理的菜单按钮权限-->
    </template>
    <template #tablePrefix="{ auth }">
      <!--【常用】表格列最左边，一般会嵌入el-table-column-->
      <!--auth表示菜单按钮权限-->
    </template>
    <template #tableSuffix="{ auth }">
      <!--【极其常用】表格列最右边，一般会嵌入el-table-column-->
      <!--auth表示菜单按钮权限-->
    </template>
    <template #tableAppend>
      <!--表格行最下方，本质上就是el-table的append插槽-->
    </template>
    <template #default>
      <!--会覆盖表格列区域，自己手写全部的el-table-column-->
    </template>
    <template #column-XXXX="{ row, item }">
      <!--【极其常用】会覆盖特定表格列，XXXX表示下方list中定义的field，一般会嵌入el-table-column-->
      <!--row表示当前行的数据，item表示下方的配置项实体-->
    </template>
    <template #table="{ auth, rawAuth, data }">
      <!--表格之外的下方，用于配合showTable，用于替换原有表格-->
      <!--rawAuth最常用，表示菜单按钮权限，auth不常用，表示经过组件内部特殊处理的菜单按钮权限，data表示列表数据-->
    </template>
    <template #edit="{ rowData, type }">
      <!--【极其常用】增改弹窗，所有表单项最下方区域-->
      <!--rowData表示编辑时初始化的数据源，type表示add/edit-->
    </template>
    <template #editButtonPrefix="{ rowData, rawAuth, type, auth }">
      <!--增改弹窗，提交按钮的左侧-->
      <!--rawAuth最常用，表示菜单按钮权限，auth不常用，表示经过组件内部特殊处理的菜单按钮权限，type表示add/edit，rowData表示编辑时初始化的数据源-->
    </template>
    <template #editButton="{ rowData, rawAuth, type, auth }">
      <!--增改弹窗，提交按钮的右侧-->
      <!--rawAuth最常用，表示菜单按钮权限，auth不常用，表示经过组件内部特殊处理的菜单按钮权限，type表示add/edit，rowData表示编辑时初始化的数据源-->
    </template>
  </table-generation>
</template>
<script>
// 请记住，一定要使用tableGenerationV2，这个是领导要求的最新版本，tableGeneration是V1版本，已经被废弃
import TableGeneration from '@/components/common/dynamicForm/tableGenerationV2/index.vue'
import {
  floodDangerInfoDangerInfoFailList,
  floodDangerInfoDangerInfoFindById, floodDangerInfoDangerInfoUpdate, floodExpertAttendanceExpertAttendanceAdd,
  floodExpertAttendanceExpertAttendanceDelete
} from '@/api/api-flood'
import { ruralRelManageUserRelManageUserModifySort } from '@/api/api-rural'

export default {
  components: {
    TableGeneration
  },
  data () {
    return {
      list: [{
        title: '',
        children: [{
          // 【必需】表格/表单弹窗中字段的标题
          title: '标题',
          // 【必需】表格/表单弹窗中接口返回的字段名，也可以用于自定义的字段名，但下列特殊情况，字段名需要定义为数组
          // 如果type为'date'，且showType带'range'，即日期范围选择器，field必须要是['开始日期字段', '结束日期字段']
          // 如果type为'timePicker'，且isRange=true，即时间范围选择器，field必须要是['开始时间字段', '结束时间字段']
          // 如果type为'wkt'，且后端需要经纬度，即经纬度选择器，field必须要是['经度字段', '纬度字段']
          // 如果type为'upload'，且后端仅仅只需要文件路径、文件名（可不要），field必须要是['文件路径字段', '文件名字段']或['文件路径字段']
          field: 'title',
          // 【必需】组件类型,请参考"src/components/common/dynamicForm/formItemGeneration/index.vue"，搜索"item.type =="
          type: 'input',
          // 【常用】组件类型下有哪些配置项,请参考"src/components/common/dynamicForm/formItemGeneration/index.vue"，搜索"item.type =="
          disabled: false,
          size: 'small',
          width: '100%',
          ...各种各样的组件配置项,
          // 【常用】在表格中表格列的配置项，其实就是el-table-column的配置项，请参考"src/components/common/dynamicForm/tableGenerationV2/index.vue"，搜索"v-for="(v, i) in columnTools""
          columnSortable: false,
          columnFixed: false,
          ...各种各样的表格列配置项,
          // 【常用】表单项对应的双向绑定值，一般无需设置，如果想要设置默认值，可以使用
          value: '默认值',
          // 【极其常用】表格/增改弹窗中表单项的单位，会展示在表单项标题的后方，例如“金额（元）”
          unit: '单位',
          // 【常用】表格中表单项的单位，一般来说unit足够使用，但如果需求中表格展示的单位和表单弹窗展示的单位不一样，例如表格需要“金额（万元）”，表单弹窗需要“金额（元）”
          unitShow: '表格列标题单位',
          // 【常用】控制该表单项是否要在增改弹窗中展示，如果想隐藏字段（相当于display: none）可以设置成false，但提交时该字段依旧会提交
          isShowInForm: true,
          // 【极其常用】控制该表单项是否要在增改弹窗中展示，如果想彻底隐藏字段（相当于v-if=false）可以设置成false，但提交时该字段不会提交
          isEdit: true,
          // 【极其常用】控制该字段是否要在表格中展示
          isShow: true,
          // 【极其常用】校验条件，支持函数自定义，字符串（推荐），数组
          // 如果想设置内置的校验条件，例如必填等等，可以设置为字符串'required'，请参考"src/components/common/dynamicForm/formItemGeneration"，搜索"rules.forEach"
          // 如果想同时设置多个校验条件，可以设置为数组['required', 'float']
          rule: (data) => {
            // 可以使用getForm获取其余字段的value
            const otherValue = this.$refs.table.runCommand('getForm', {
              target: 'otherField',
              field: 'value'
            })
            if (data && data.length > 200) {
              // 如果返回字符串，则会自动判断为校验失败，会在表单项下方展示出来这个字符串作为校验失败的提示
              return '数据长度不能超过200位'
            } else if (otherValue && otherValue.length > 200) {
              // 这里一定要注意，关联字段的修改并不会触发当前字段的校验，必须要搭配formChange事件和this.$refs.table.runCommand('refreshCheck')，手动触发一次校验
              return '关联字段不能超过200位'
            } else {
              return true
            }
          },
          // 【极其常用】如果设置triggerEditing为true，则将该字段样式改为可点击形态，点击后会触发编辑弹窗；如果设置为方法，则将该字段样式改为可点击形态，点击后会触发方法
          // triggerEditing: (row) => {},
          triggerEditing: false,
          // 【不常用】增改弹窗中,该表单项对应的标题盒子长度，可以设置成css中width可以设置的所有值，包括“20%”，“10vw”等等
          formTitleWidth: '100px',
          // 【不常用】增改弹窗中,该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，可以使用默认内置的图标，暂时只内置了“required”必填图标
          titleIcon: 'required',
          // 【不常用】增改弹窗中,该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，除了默认内置的图标，也支持自定义图标，图标class可以参考“https://fontawesome.com.cn/v4/icons”
          titleIconClass: 'fa fa-asterisk',
          // 【不常用】增改弹窗中,该表单项对应的标题盒子，支持用相对布局给标题周围新增一个图标，除了默认内置的图标位置，也支持自定义位置
          titleIconStyle: {
            position: 'absolute',
            top: '-4px',
            left: '-9px',
            transform: 'scale(0.6)'
          },
          // 【不常用】表格支持动态配置展示列，但有些列我们希望不被动态控制，这时就可以用这个属性，数组代表[是否被动态列控制，控制页面默认是否被选中]
          isShowInTool: [true, true],
          // 【不常用】新增时，正常情况下每次打开新增弹窗，value都会被重置，当smartCache设置为true，每次打开新增弹窗时保留用户上一次新增填入的value
          smartCache: false,
        }]
      }, {
        // 对表格展示没影响，仅对增改弹窗生效
        title: '增改弹窗的字段分组标题',
        children: [{
          title: '标题1',
          field: 'title1',
          type: 'input'
        }]
      }],
      config: {
        // 【必需】表格的唯一标识符，绝对不允许重复
        // 获取方式：打开F12，会在控制台中会给你一个独属于这个表格的UUID，把这个UUID复制进来就行
        tableId: 'xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx',
        // 【必需】后端接口实体中定义的ID字段，例如“id”，“fdId”等等
        id: 'id',
        // 【必需】是否让表格盛满容器，默认为false，但99%的情况下，都是需要设置为true
        isfullHeight: true,
        // 【必需】查询条件列表，配置项属性和上边list中一致
        query: [{
          title: '查询条件',
          field: 'title',
          type: 'input'
        }],
        // 【必需】表格列表查询需要用到的配置项
        show: {
          // 【常用】对查询条件进行特殊处理
          queryFormat: (query) => {
            return {
              ...query
            }
          },
          // 【常用】对后端返回的数据进行特殊处理
          format: (dataList) => {
            return dataList.map(v => ({
              ...v
            }))
          },
          // 【必需】表格列表查询用的接口，支持两种方式，第一是最常用的直接写API，第二种是用callBack自定义api
          // method: {
          //   callBack: (query) => {
          //     return query.showType === 'configure' ? floodDangerInfoDangerInfoFailList : floodDangerInfoDangerInfoApproveList
          //   }
          // }
          method: floodDangerInfoDangerInfoFailList,
          // 【常用】针对于某些字典字段，后端没有返回对应的中文，且option是前端本地写死的，该属性设置为true，会在表格上自动展示该字典字段对应的中文
          autoFixFieldShow: false,
          // 【常用】用于特殊处理后端返回数据的字段路径，一般来说后端都会'data.data.dataList'，但也有时候会用'data.data'等等，用具体用法可以看lodash的get函数
          dataPath: 'data.data.dataList',
          // 【不常用】树形表格每次刷新后，如果设置为true则自动展开刷新前已经展开的节点，如果设置为false则所有节点全部收缩
          expandRowKeys: false,
          // 【不常用】正常情况下，任意筛选条件改变后，会自动触发表格刷新，但有些特殊情况查询条件改变后不想触发表格刷新，则可以使用该属性，数组中定义的filed不会触发表格刷新
          autoQueryFilter: ['title', 'keyword'],
          // 【不常用】正常情况下，组件会通过el-table的属性，自动获取当前表格选中的行数据，但有些时候会由于业务弃用el-table，改为其余表格组件，这时可以自定义获取表格选中项的数据来源
          selectionFormat: () => {
            return []
          }
        },
        // 【必需】列表记录详情查询需要用到的配置项，90%情况下需要用到
        detail: {
          // 【必需】详情查询用的接口
          method: floodDangerInfoDangerInfoFindById,
          // 【常用】详情接口需要的传参KEY
          paramKey: 'id',
          // 【常用】详情接口如果不仅仅需要传ID，还需要传递其他参数，可以自定义传参
          queryFormat: (rowData) => {
            return {}
          },
          // 【常用】对后端返回的数据进行特殊处理
          format: (data) => {
            return {
              ...data
            }
          }
        },
        // 【极其常用】新增操作需要用到的配置项
        add: {
          // 【必需】新增用的接口，支持两种方式，第一是最常用的直接写API，第二种是用callBack自定义api
          // method: {
          //   callBack: (data, rowData) => {
          //     return data.showType === 'configure' ? floodExpertAttendanceExpertAttendanceAdd : floodExpertAttendanceExpertAttendanceAdd
          //   }
          // }
          method: floodExpertAttendanceExpertAttendanceAdd
        },
        // 【极其常用】编辑操作需要用到的配置项
        edit: {
          // 【必需】编辑用的接口，支持两种方式，第一是最常用的直接写API，第二种是用callBack自定义api
          // method: {
          //   callBack: (data, rowData) => {
          //     return data.showType === 'configure' ? floodDangerInfoDangerInfoUpdate : floodDangerInfoDangerInfoUpdate
          //   }
          // }
          method: floodDangerInfoDangerInfoUpdate
        },
        // 【极其常用】删除操作需要用到的配置项
        del: {
          // 【必需】删除操作用的接口，支持两种方式，第一是最常用的直接写API，第二种是用callBack自定义api
          // method: {
          //   callBack: (selection) => {
          //     return selection.length > 1 ? floodExpertAttendanceExpertAttendanceDelete : floodExpertAttendanceExpertAttendanceDelete
          //   }
          // }
          method: floodExpertAttendanceExpertAttendanceDelete,
          // 【常用】删除接口需要的传参KEY
          paramKey: 'ids',
          // 【常用】删除接口如果不仅仅需要传ID逗号分隔，还需要传递其他参数，可以自定义传参
          format: (selection) => {
            return {}
          },
          // 【不常用】删除前提示窗的提示语句
          confirmText: '此操作将永久删除, 是否继续?'
        },
        // 【不常用】列表批量排序用到的配置项
        sort: {
          // 【必需】排序用的接口，一般来说排序接口的传参方式是固定的，不建议后端自由发挥
          method: ruralRelManageUserRelManageUserModifySort,
          // 【必需】排序接口需要的传参KEY
          paramKey: 'sortJSON',
          // 【必需】列表接口中的排序字段
          key: 'sort',
          // 【必需】对排序项的标题进行格式化
          format: v => `${v.name}（${v.tel}）`
        },
        // 【不常用】导出用到的配置项
        export: {
          // 【必需】导出用到的接口
          method: {
            // 【不必需】用户想要导出表格勾选的数据时，用到的接口
            single: '/project/scene/projectBase/exportQRCode',
            // 【必需】用户想要导出查询条件对应的所有数据时，用到的接口
            multi: '/project/scene/projectBase/exportQRCode'
          },
          // 【常用】导出接口如果不仅仅需要默认传参，还需要传递其他参数，可以自定义传参
          queryFormat: (query) => {
            return {
              ...query
            }
          },
          // 【不常用】如果type不填，默认导出是直接用JS方法进行导出（适配90%情况），但有些情况下，JS导出会失败，这时可以设置为1，直接使用window.open
          type: 1,
        },
        // 【极其常用】新增或编辑提交前，触发该回调，回调函数里可以对待提交的数据进行特殊处理
        sumitCallback: (data, type, rowData) => {
          // data：待提交的数据, type：add/edit, rowData：编辑时初始化的数据源
          // 如果直接返回false，则会取消掉该次提价
          // return false
          return {
            ...data
          }
        },
        // 【不常用】新增或编辑提交后，触发该回调，res：接口返回的结果，data：提交给接口的数据, type：add/edit, rowData：编辑时初始化的数据源
        sumitAfterCallback: (res, data, type, rowData) => {
        },
        // 【常用】【已废弃】是否需要分页，如果设置为true，分页器会自动隐藏，pageSize会直接传9999，但这个有问题，2022年以后的接口pageSize接到9999后，只会查询9999条数据，不会拿所有数据
        showAll: false,
        // 【常用】是否需要分页，如果设置为true，分页器会自动隐藏，pageSize会直接传0
        showAllNew: false,
        // 【常用】如果发现弹出的增删改查弹窗被遮罩覆盖，请设置为true
        appendToBody: false,
        // 【常用】增改弹窗的弹窗宽度，推荐设置，自己写死一个最好看的固定px，例如850px等等
        dialogWidth: '45%',
        // 【常用】表格配置项,请参考"src/components/common/dynamicForm/tableGenerationV2/index.vue"，搜索"<el-table"
        rowKey: false,
        ...elTable的配置项,
        // 【不常用】如果弹窗的标题不想用默认的“新增/编辑”，可以自定义
        dialogTitle: '自定义弹窗标题',
        // 【不常用】是否隐藏增改弹窗中的提交按钮
        hideSubmit: false,
        // 【不常用】组件初始化是是否要请求接口
        loadFirst: true,
        // 【不常用】是否要展示表格
        showTable: true,
        // 【不常用】是否要展示分页器，一般不需要设置
        showPaging: true,
        // 【不常用】一般来说按钮权限都是组件自动根据URL路径后缀获取，但有些特殊情况，例如菜单A和菜单B都需要使用该组件，按钮权限要求都使用菜单A的，那这里就必须要把获取按钮权限的URL路径后缀写死
        authPath: 'projectfinishaccept',
        // 【不常用】表格是否为无需请求接口的静态表格，如果设置为true，则表格通过前端本地逻辑实现增删改查
        isStatic: false,
        // 【不常用】新增/编辑按钮点击后不触发新增/编辑弹窗，一般和buttonClicked事件搭配使用，用于自定义新增/编辑按钮的点击事件
        disableButtonEvent: false
      }
    }
  },
  methods: {
    // 【极其常用】组件初始化完成的回调，任何对表格、查询条件等表格相关的处理，必须要在此函数内执行
    afterInit() {
      // 【极其常用】【极其重要】组件只暴露出runCommand一个方法供开发使用，绝对不允许通过$refs.table获取其他属性或方法进行调用或修改
      // 请参考"src/components/common/dynamicForm/tableGenerationV2/index.vue"，搜索"runCommand ("
      this.$refs.table.runCommand()
    },
    // 【极其常用】增改弹窗初始化完成的回调，任何对增改弹窗，表单项等表单相关的处理，必须要在此函数内执行
    // rowData是表单初始化用到的数据源，type是add/edit
    afterDialogInit(rowData, type) {
      // 【极其常用】【极其重要】组件只暴露出runCommand一个方法供开发使用，绝对不允许通过$refs.table获取其他属性或方法进行调用或修改
      // 请参考"src/components/common/dynamicForm/common/tableGenerationEditCommon.js"，搜索"runCommand ("
      // 当在增改弹窗初始化完成后，runCommand会支持更多的方法
      this.$refs.table.runCommand()
    },
    // 【极其常用】增改弹窗里的表单触发事件的回调
    // field是表单项的field, eventName是表单项触发的事件名, e是表单项触发的事件回调的参数
    formChange (field, eventName, e) {
      // 监听事件一定要写明field和eventName，绝对不能偷懒，否则会造成多次触发
      // 例如只写了“field === 'title'”，但title表单项存在多个事件，最后，所有这个表单项的事件都会触发这段代码
      if (field === 'title' && eventName === 'change') {
        console.log(e)
      }
    },
    // 【极其常用】表格里的查询条件表单触发事件的回调
    // field是表单项的field, eventName是表单项触发的事件名, e是表单项触发的事件回调的参数
    queryChange (field, eventName, e) {
      // 监听事件一定要写明field和eventName，绝对不能偷懒，否则会造成多次触发
      // 例如只写了“field === 'title'”，但title表单项存在多个事件，最后，所有这个表单项的事件都会触发这段代码
      if (field === 'title' && eventName === 'change') {
        console.log(e)
      }
    },
    // 【常用】新增编辑弹窗点击提交，然后接口成功返回结果后，会触发此回调
    // data是接口返回的数据
    close(data) {
    },
    // 【常用】新增编辑弹窗关闭（可能是点了关闭按钮，也可以是点击了提交等等）后，会触发此回调
    // rowData表单初始化用到的数据源，type是add/edit
    closeDialog({ type, rowData }) {
    },
    // 【常用】针对于动态表格，当表格数据发生变化时，例如分页，刷新等，会触发该事件
    // dataList是表格数据，requestData接口返回实体
    tableDataChangeV2 ({
                         dataList,
                         requestData
                       }) {
    },
    // 【常用】只是写了其中一个示例，远不止这一个，支持el-table触发的所有事件，请参考"src/components/common/dynamicForm/tableGenerationV2/index.vue"，搜索"@row-click"
    // 如果想知道el-table有哪些事件，事件有哪些参数，请到element-ui官网去看
    tableRowClick () {
    },
    // 【不常用】针对于静态表格，当表格数据发生变化时，例如分页，刷新等，会触发该事件
    tableDataChange (dataList) {
    },
    // 【不常用】表格删除操作完成后会触发该事件
    // list代表勾选的表格数据
    tableDeleteDataNew (list) {
    },
    // 【不常用】点击新增/编辑按钮后会触发这个事件
    // rowData表单初始化用到的数据源，type是add/edit
    buttonClicked (type, rowData) {
    },
    // 【不常用】点击筛选重置按钮后触发
    resetQuery () {
    },
  }
}
</script>
